package com.bizfx.component.controls
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import com.bizfx.collections.HashMap;
	import com.bizfx.component.IBizApplication;
	import com.bizfx.component.views.ViewCommand;
	import com.bizfx.events.CommandRaiseEvent;
	import com.bizfx.utils.ListUtils;
	import com.bizfx.utils.StringUtils;
	
	import mx.collections.ArrayCollection;
	import mx.collections.IList;
	import mx.containers.Box;
	import mx.containers.HBox;
	import mx.controls.Button;
	import mx.controls.Menu;
	import mx.controls.PopUpButton;
	import mx.controls.menuClasses.MenuListData;
	import mx.core.Application;
	import mx.events.CollectionEvent;
	import mx.events.MenuEvent;
	
	import org.springextensions.actionscript.core.command.event.CommandEvent;
	
	[Event(name="commandRaise", type="com.bizfx.events.CommandRaiseEvent")]

	public class CommandBar extends Box implements ICommandBar
	{	
		private var commandButtonMap:HashMap = new HashMap();

		private var container:HBox = new HBox();
		
		private var commandsDirty:Boolean = false;
		
		private var _commands:IList;
		
		[Bindable("commandsChanged")]
		public function get commands():IList {
			if (this._commands == null) {
				this._commands = new ArrayCollection();
				this._commands.addEventListener(CollectionEvent.COLLECTION_CHANGE, commandsChangeHandler);
			}
			return _commands;
		}
		
		public function set commands(value:IList):void {
			if (this._commands != value) {
				this.commandsDirty = true;
				if (this._commands) {
					this._commands.removeEventListener(CollectionEvent.COLLECTION_CHANGE, commandsChangeHandler);
				}
				this._commands = value;
				if (this._commands) {
					this._commands.addEventListener(CollectionEvent.COLLECTION_CHANGE, commandsChangeHandler);
				}
				this.dispatchEvent(new Event("commandsChanged"));
				this.invalidateDisplayList();
			}
		}
		
		public function CommandBar() {
			super();
		}
		
		override protected function createChildren(): void {
			super.createChildren();
			this.container.percentWidth = 100;
			this.container.percentHeight = 100;
			this.addChild(this.container);
			
			var cNum:int = this.commands.length;
			for (var i:int; i < cNum; i++) {
				var command:ViewCommand = ViewCommand(this.commands.getItemAt(i));
				this.appendCommand(command);
			}
		}
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			
			if (this.horizontalAlignDirty) {
				this.horizontalAlignDirty = false;
				this.container.setStyle("horizontalAlign", this.getStyle("horizontalAlign"));
			}
			
			if (this.commandsDirty) {
				this.commandsDirty = false;
				//删除所有按钮
				for (var i:int; i < commandButtonMap.size(); i++) {
					var o:DisplayObject = DisplayObject(commandButtonMap.values()[i]);
					this.container.removeChild(o);
				}
				this.commandButtonMap.clear();
				
				var cNum:int = this.commands.length;
				for (var j:int; j < cNum; j++) {
					var command:ViewCommand = ViewCommand(this.commands.getItemAt(j));
					this.appendCommand(command);
				}
			}
		}
		
		private var horizontalAlignDirty:Boolean = true;
		
		override public function styleChanged(styleProp:String):void {
			super.styleChanged(styleProp);  
			switch(styleProp) {  
				case "horizontalAlign":  
					horizontalAlignDirty = true;
					invalidateDisplayList();
					break;  
			}  
		}
		
		protected function appendCommand(command:ViewCommand):void {
			if (StringUtils.isNullOrEmpty(command.permissionCode)
				|| ListUtils.isContains(command.permissionCode, IBizApplication(Application.application).userPermissions)) {
				if (StringUtils.isNullOrEmpty(command.groupName)) {
					var button:Button = new Button();
					button.label = command.commandName;
					button.data = command;
					button.setStyle("icon" ,command.icon);
					button.addEventListener(MouseEvent.CLICK, commandButtonClickHandler);
					this.commandButtonMap.put(command.commandKey, button);
					this.container.addChild(button);
				} else {
					var buttonGroup:PopUpButton = null;
					if (!this.commandButtonMap.containsKey(command.groupName)) {
						buttonGroup = new PopUpButton();
						buttonGroup.openAlways= true;
						buttonGroup.label = command.groupName;
						buttonGroup.data = command;
						buttonGroup.setStyle("icon" ,command.icon);
						var menu:Menu = new Menu();
						menu.setStyle("textAlign", "left");
						menu.addEventListener(MenuEvent.ITEM_CLICK, menuItemClickHandler);
						menu.labelField = "commandName";	
						menu.dataProvider = new ArrayCollection();
						ArrayCollection(menu.dataProvider).addItem(command);
						buttonGroup.popUp = menu;
						this.commandButtonMap.put(command.groupName, buttonGroup);
						this.container.addChild(buttonGroup);	
					} else {
						buttonGroup = PopUpButton(this.commandButtonMap.get(command.groupName));
						buttonGroup.popUp["dataProvider"].addItem(command);
					}
				}
			}
		}

		public function hideAllCommands():void {
			for (var i:int; i < commandButtonMap.size(); i++) {
				var o:Button = Button(commandButtonMap.values()[i]);
				o.visible = false;
				o.includeInLayout = false;
			}
		}
		
		public function showCommandByKey(commandKey:String):void {
			if (this.commandButtonMap.containsKey(commandKey)) {
				var o:Button = Button(commandButtonMap.get(commandKey));
				o.visible = true;
				o.includeInLayout = true;
			}
		}
		
		/**
		 * Event Handlers 
		 */
		
		private function commandButtonClickHandler(event:MouseEvent):void {
			this.enabled = false;
			try {
				var command:ViewCommand = event.target.data as ViewCommand;
				if (command != null) {
					this.dispatchEvent(new CommandRaiseEvent(command));
				}
			} catch (error:Error){
			} finally {
				this.enabled = true;
			}
		}
		
		private function menuItemClickHandler(event:MenuEvent):void {
			this.enabled = false;
			try {
				var command:ViewCommand = event.item as ViewCommand;
				if (command != null) {
					this.dispatchEvent(new CommandRaiseEvent(command));
				}
			} catch (error:Error){
			} finally {
				this.enabled = true;
			}
			
		}
		
		protected function commandsChangeHandler(event:CollectionEvent):void {
			this.commandsDirty = true;
		}
	}
}